import knowledge
import nltk
import en
import random

class FactSpec(object):
  fact = None
  aspect = None
  which = None
  def __init__(self, fact=None, aspect=None, which=None):
    self.fact = fact
    self.aspect = aspect
    self.which = which
  def __str__(self):
    return str(self.fact) + '.' + str(self.aspect) + ': ' + str(self.which)

import manage

def debug(*strings):
  return
  for s in strings:
    print s,
  print

''' Present is a wrapper function that takes a behavior and facts and pushes
    those facts to the appropriate function '''
def present(behavior, facts):
   	if type(behavior) is manage.Transition:
		transition(behavior,facts)
	if type(behavior) is manage.Query:
		query(facts)
	if type(behavior) is manage.DeclarativeSingle:
		declareSingle(facts)
	if type(behavior) is manage.DeclareTriple:
		declareTriple(facts)
	if type(behavior) is manage.Answer:
		answer(facts)

''' Handles output for the transistion between two topics '''
def transition(behavior):
	target = ""
	ffact = behavior.fromFact.fact
	faspect = behavior.fromFact.aspect
	fwhich = behavior.fromFact.which
	fact = behavior.newFact.fact
	aspect = behavior.newFact.aspect
	which = behavior.newFact.which
	commonality = behavior.commonality
	date = ""
	
	if behavior.commonality == "time r":
		target += "Also "
		if type(fwhich) == knowledge.Date:
			date += "in " + fwhich.string()
		if type(fwhich) == knowledge.Event:
			date += "in " + fwhich.start.string()
	if behavior.commonality == "time":
		if type(fact) == knowledge.Event:
			if aspect in ("start","end"):
				target += factEnglish(behavior.fromFact) + ", the same time that " + \
				 str(fact.subject) + " " + conjugate(str(fact.verb))
				return target
		else:
			target +=factEnglish(behavior.fromFact) + "  At the same time, " 
	if behavior.commonality == "location r" :
		target +="Also in " + which.name + ", "
	if behavior.commonality == "location" :
		target +=factEnglish(behavior.fromFact) + " Also in " + behavior.fromFact.which.name + ", "
	x =factEnglish(behavior.newFact)
	if (date is not ""):
		x=x.replace(date,"")
		target += date + ", " + x
	else:
		target += x + "."
		
	
	return trim(target)
	
'''  Presents fact in behavior as a question  '''

def query (behavior):
	options = []
	options.append ( trim("Were you aware that "  + factEnglish(behavior.fact) + "?"))
	options.append( trim("Did you know "  + factEnglish(behavior.fact) + "? "))

	return random.choice(options)

'''  Presents one fact taken from behavior as a declaration '''

def declareSingle (behavior):
	options = []
	options.append (trim("Well, " + factEnglish(behavior.fact) + "."))
	options.append  (trim(factEnglish(behavior.fact) + "."))
	options.append ( trim("I can tell you that " + factEnglish(behavior.fact) + "."))
	options.append (trim("Remember, " + factEnglish(behavior.fact) + "."))
	
	return random.choice(options)

'''  Presents three facts from the behavior as declarations '''

def declareTriple (behavior):
	target = ""
	target += "Well, "  + factEnglish(behavior.facts[0]) + ". Also, "  + factEnglish(behavior.facts[1]) 
	target += ". And, "  + factEnglish(behavior.facts[2]) + "."
	return trim(target)
'''  Presents the answer to a user submitted question '''

def answer (behavior):
	return trim("Oh, " + factEnglish(behavior.fact) + "." )
	

'''  This workhorse function converts a fact relation, expressed in a
     factSpec as natural language.  Other functions supply a simple wrapper
     around the output of factEnglish to complete the sentence.   ''' 

def conjugate (verb):
	target = ""
	token = nltk.WhitespaceTokenizer()
	x = token.tokenize(verb)
	x[0] = en.verb.past(x[0],person=1)
	for y in x:
		target += y + " "
	return target

def trim (line):
	line = line.replace("date unknown","")
	line = line.replace("-","")
	line = line.replace("  ", " ")
	line = line.replace(" .",".")
	line = line.replace(" ?","?")
	line = line.replace("( ","(")
	line = line.replace(" )",")")
	return line

def factEnglish (facts):
	target = ""
	options = []
	if (facts is not list) :
		fact = facts.fact
		aspect = facts.aspect
		which = facts.which
                debug('Fact:', fact)
                debug('Aspect:', aspect)
                debug('Which:', which)

		if type(fact) == knowledge.Event:
			debug("Event.object = " + str(fact.object))
			debug("Event.verb = " + str(fact.verb))
			
		if type(which) == knowledge.Event:
			debug("Event.object = " + str(which.object))
			debug("Event.verb = " + str(which.verb))
	
		if (type(fact) ==  knowledge.Location):
			if aspect == "events" :
				options.append(which.name + " " + fact.name)
			elif aspect == "contains" :
				options.append( which.name + " " + fact.name)
			elif aspect == "within" :
				options.append(fact.name + " " + which.name)


		if type(fact) == knowledge.Person:
			if aspect == "birth" :
				target += (fact.name + " was born")
				if (which.start == None):
					options.append(trim(target))
				else:
					if (which.start.day) :
						target += " on " 
					else : 
						target += " in " 
					debug (which.start.string())
					target += which.start.string()
					options.append(trim(target))
									
			elif aspect == "death" :
				target += fact.name + " died" 
				if (which.start == None):
					options.append(target)
				else:
					if (which.start.day) :
						target += " on " 
					else : 
						target += " in " 
						target += which.start.string()
						options.append(trim(target))
			
			elif aspect == "caused" :
				target = which.name.replace(fact.name,"")
				if (target == which.name) :
					 target = fact.name + " " + which.name
					 options.append(trim(target))
				else:
					 target = fact.name + " " + which.name
					 options.append(trim(target))
							 
			elif aspect == "participated":
				target = fact.name + " " + which.name.replace(fact.name,"")
				options.append(trim(target))
		
		if type(fact) == knowledge.Event:
			if aspect in ("start", "end")\
			and fact.start == fact.end:
				if (which.day):
					target += " on "
				else:
					target += " in "
				target += which.string()
				verb = conjugate(fact.verb)
				name = fact.name.replace(fact.verb,verb)
				name = name.replace(target,"") + target
				options.append(trim(name))

			if aspect == "location" :
				options.append(fact.name + " " + which.name)				
			elif aspect == "causes" :
				target = fact.name + " " + which.name
				options.append(trim(target))
				
			elif aspect == "results":
				options.append(fact.name + " " + which.name)	
			
			elif aspect == "instigators" :
				target = fact.name.replace(which.name,"")
				target = target.replace(fact.verb,conjugate(fact.verb))
				target = which.name + "" + target
				options.append(trim(target))
			
			elif aspect == "participants" :
				target = fact.name.replace(which.name,"")
				target = target.replace(fact.verb,conjugate(fact.verb))
				target = which.name + "" + target
				options.append(trim(target))
			
				
		if type(fact) == knowledge.Group:
			if aspect == "members" :
				options.append(which.name + " was a member of "  + fact.name)
				
	
		if type(fact) == knowledge.Object:
			if aspect == "creation": 
				target += fact.name + " was created " 
				if (which.day) :
					target += "on " 
				else : 
					target += "in " 
				target += which.string()
				options.append(target)
			elif aspect == "creator" :
				options.append(fact.name + " " + which.name)
			elif aspect == "location" :
				options.append(fact.name + " " + which.name)
				
	return random.choice(options)

'''  Returns greeting, asks user to pick between two topics expressed in 
     factSpec (fact and which) or supply their own topic '''

# Lots of canned text to pull from randomly here.

def intro(facts):
	fact = facts.fact
	which = facts.which
	target = ""
	target += "Hi. Welcome to flamingsquirrel, the history chat bot.  I know"
	target += " a lot about the history of the Renaissance.  Would you like to"
	target += " know about " + fact.name + " or " + which + " or maybe "
	target += "something entirely different?"
	return target

def confirm (facts):
	fact = facts.fact
	which = facts.which
	target = ""
	target += "Did you mean " + fact.name + "?"
	return target

def respond ():
	options = []
	options.append("Are you still there?")
	options.append("Please respond.")
	options.append("Hey!  Where'd you go?")
	options.append("You seem to have left, is there anything I can help you with?")
	options.append("You there?")
	return random.choice(options)

def bye () :
	options = []
	options.append("Thanks for letting me chew your ear.")
	options.append("See you 'round.")
	options.append("Bored already?  Talk to you later.")
	options.append("Nice chatting with you.")
	return random.choice(options)
	

	
	
	
	
